package com.wrupple.muba.catalogs.client.widgets.fields.cells;

import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.shared.EventBus;
import com.wrupple.muba.catalogs.client.activity.process.task.CatalogInteractionState.Mode;
import com.wrupple.muba.common.client.application.DataCallback;
import com.wrupple.muba.common.shared.Process;
import com.wrupple.muba.common.shared.State.ProcessManager;
import com.wrupple.vegetate.domain.FieldDescriptor;

public abstract class AbstractDelegatingEditableField<T> extends AbstractEditableField<T> {

	private class Recepient extends DataCallback<T> {

		@Override
		public void execute() {
			lockAllEvents = false;
			if (result != null) {
				finishEditing(result);
			} else {
				finishEditing(null);
			}
		}

	}

	protected ProcessManager pm;
	private EventBus bus;

	public AbstractDelegatingEditableField(EventBus bus,ProcessManager pm,FieldDescriptor d, Mode mode) {
		super(d, mode);
		this.pm=pm;
		this.bus=bus;
	}

	@Override
	protected void onValueWillCommit(Element parent, FieldData<T> viewdata) {

	}

	@Override
	protected void onEditModeEvent(Context context, Element parent, T value, FieldData<T> viewData, NativeEvent event,
			ValueUpdater<T> valueUpdater) {
		String type = event.getType();
		int keyCode = event.getKeyCode();
		if ("click".equals(type) || ("keyup".equals(type) && keyCode == KeyCodes.KEY_ENTER)) {
			onWillEnterEditMode(parent, viewData);
		}
	}

	@Override
	protected void onWillEnterEditMode(Element parent, FieldData<T> viewdata) {
		if (pm != null) {
			try {
				lockAllEvents = true;
				Process<T, T> selectingProcess = getDelegateProcess();
				Recepient recepient = new Recepient();
				T inputValue = getCurrentInputValue(parent, true);
				pm.processSwitch(selectingProcess, getProcessLocalizedName(), inputValue ,
						recepient,getBus());
			} catch (Exception e) {
				GWT.log("something went wrong invoking process", e);
			}
		}
	}

	protected abstract String getProcessLocalizedName();

	protected abstract Process<T, T> getDelegateProcess();

	public EventBus getBus() {
		return bus;
	}


	public ProcessManager getProcessManager() {
		return pm;
	}

	public FieldDescriptor getFieldDescriptor() {
		return fieldDescriptor;
	}

	public Mode getMode() {
		return mode;
	}


}
